package net.homeip.net.tinframework.filter;

import java.io.IOException;
import java.util.Locale;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.jstl.core.Config;

import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import net.homeip.net.tinframework.constants.FrameworkConstants;
import net.homeip.net.tinframework.util.CookieUtil;

/**
 * @author: Roger Chu
 * @category: tinFramework
 * 
 * Sets locale for the web layer.
 * 
 */
public class LocaleFilter implements Filter {

	public static final String LOCALE_PARAMETER = "locale";
	public static final String LOCALE_COOKIE = "localeID";
	public static final int COOKIE_MAX_AGE_DAYS = 62;

	public void init(FilterConfig filterConfig) throws ServletException {
	}

	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) servletRequest;
		HttpServletResponse response = (HttpServletResponse) servletResponse;
		HttpSession session = request.getSession();

		String localeParameter = request.getParameter(LOCALE_PARAMETER);

		// first check request parameter
		Locale locale = decideLocale(localeParameter);
		if (locale != null) {
			// set locale cookie
			CookieUtil.setCookie(response, LOCALE_COOKIE, LOCALE_PARAMETER, COOKIE_MAX_AGE_DAYS);
		} else {
			// next check locale cookie
			String localeCookie = CookieUtil.getCookie(request, LOCALE_COOKIE);
			locale = decideLocale(localeCookie);
		}

		if (locale == null) // no parameter or cookie
		{
			locale = (Locale) session.getAttribute(FrameworkConstants.LOCALEID);
			if (locale == null) // not set in session
			{
				locale = request.getLocale(); // try browser setting
			}
		}

		if (locale != null) {
			// set Spring locale
            SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
            sessionLocaleResolver.setLocale(request,response,locale); 
            request.getSession().setAttribute(FrameworkConstants.LOCALEID, locale);

			// set JSTL locale
			Config.set(session, Config.FMT_LOCALE, locale);
		}

		// continue with remaining filters
		filterChain.doFilter(servletRequest, servletResponse);

	}

	private Locale decideLocale(String localeId) {
		Locale locale = null;

		if (localeId != null) {
			if (localeId.length() == 2) {
				locale = new Locale(localeId);
			}
			else if (localeId.length() == 5) {
				locale = new Locale(localeId.substring(0, 2), localeId.substring(3, 5));
			}
		}

		return locale;
	}

	public void destroy() {
	}

}
